<?php

// $Id: rdf2dot.php,v 1.1 2006/03/20 23:16:59 rdmp1c Exp $

error_reporting(0); // The appmosphere classes generate warnings, so we suppress these

include_once("ARC_rdfxml_parser.php");

function rdf2dot($file_name)
{
	$dot = '';
	
	// RDF parser
	$parser_args=array(
	  "bnode_prefix"=>"genid",
	  "base"=>""
	);
	$parser=new ARC_rdfxml_parser($parser_args);

	$triples=$parser->parse_file($file_name);
	
	if(is_array($triples))
	{
	  $nodes = array();
	  $edges = array();
	  
	  $node_count = 0;
	  $result="";
	  for($i=0,$i_max=count($triples);$i<$i_max;$i++){
		$cur_t=$triples[$i];
		/* s */
		$cur_s=$cur_t["s"];
		
		$source = '';
		$cur_s_type=$cur_s["type"];
		if($cur_s_type==="uri")
		{
		  $result.=$cur_s["uri"];
		  $source = $cur_s["uri"];
		  $label = $source;
		}
		elseif($cur_s_type==="bnode")
		{
		  $result.=$cur_s["bnode_id"];
		  $source = $cur_s["bnode_id"];
		}
		$result.=" ";
		
		
		// Source node
		if (!isset ($nodes[$source]))
		{
			$label = $source;
			if ($cur_s_type==="bnode") { $label = "";}
			$nodes[$source] = array("id" => $node_count, "label" => $label, "type" => $cur_s_type);
			$node_count++;
		}
		
		$source_id = $nodes[$source]["id"];
		
		/* p */
		$cur_p=$cur_t["p"];
		$result.=$cur_p;
		$result.=" ";
		
		$edge_label = $cur_p;
	
		
		// Strip namespace
		if (preg_match("/urn:lsid:/", $edge_label))
		{
			$edge_label = strrchr($cur_p, ":");
			$edge_label = str_replace (":", "", $edge_label);
		}
		else if (preg_match("/http:\/\/xmlns.com\/foaf\/0.1\//", $edge_label))
		{
			$edge_label = preg_replace ("/http:\/\/xmlns.com\/foaf\/0.1\//", "foaf:", $edge_label);
		}
		else if (preg_match("/http:\/\/www.w3.org\/1999\/02\/22-rdf-syntax-ns#/", $edge_label))
		{
			$edge_label = preg_replace ("/http:\/\/www.w3.org\/1999\/02\/22-rdf-syntax-ns#/", "rdf:", $edge_label);
		}
		else if (preg_match("/http:\/\/www.w3.org\/2000\/01\/rdf-schema#/", $edge_label))
		{
			$edge_label = preg_replace ("/http:\/\/www.w3.org\/2000\/01\/rdf-schema#/", "rdfs:", $edge_label);
		}
		else if (preg_match("/http:\/\/purl.org\/dc\/elements\/1.1\//", $edge_label))
		{
			$edge_label = preg_replace ("/http:\/\/purl.org\/dc\/elements\/1.1\//", "dc:", $edge_label);
		}
		else if (preg_match("/http:\/\/prismstandard.org\/namespaces\/1.2\/basic\//", $edge_label))
		{
			$edge_label = preg_replace ("/http:\/\/prismstandard.org\/namespaces\/1.2\/basic\//", "prism:", $edge_label);
		}
		else if (preg_match("/http:\/\/purl.org\/rss\/1.0\//", $edge_label))
		{
			$edge_label = preg_replace ("/http:\/\/purl.org\/rss\/1.0\//", "rss:", $edge_label);
		}
		else if (preg_match("/http:\/\/purl.org\/rss\/1.0\/modules\/syndication\//", $edge_label))
		{
			$edge_label = preg_replace ("/http:\/\/purl.org\/rss\/1.0\/modules\/syndication\//", "sy:", $edge_label);
		}
		else if (preg_match("/http:\/\/purl.org\/dc\/terms\//", $edge_label))
		{
			$edge_label = preg_replace ("/http:\/\/purl.org\/dc\/terms\//", "dcterms:", $edge_label);
		}
	
	
		/* o */
		$cur_o=$cur_t["o"];
		$target = '';
		
		$cur_o_type=$cur_o["type"];
		if($cur_o_type==="uri"){
		  $result.=$cur_o["uri"];
		  
		  $target = $cur_o["uri"];
	
		}
		elseif($cur_o_type==="bnode"){
		  $result.=$cur_o["bnode_id"];
		  $target = $cur_o["bnode_id"];
		}
		elseif($cur_o_type==="literal"){
		  $result.=$cur_o["val"];
		  
		  $target = $cur_o["val"];
	
		  if($dt=$cur_o["dt"]){
			$result.=" (dt: ".$dt.")";
		  }
		  elseif($lang=$cur_o["lang"]){
			$result.=" (lang: ".$lang.")";
		  }
		}
		
		
	   // Target node
		if (!isset ($nodes[$target]))
		{
			$label = $target;
			if ($cur_o_type==="bnode"){ $label = ""; }
			
			if ($cur_o_type=="literal")
			{
				// Trim long literal nicely
				$length = 30;
				if (strlen($label) > $length)
				{
					$label = substr ($label, 0, $length);
	/*				$pos = strrpos ($label, ' ');
					if (!$pos) { $pos == $length; }
					$label = substr ($label, 0, $pos);*/
					$label .= '...';
					
					// Escape quotes
					$label = str_replace ('"', '\"', $label);
				}
			}
			
			$nodes[$target] = array("id" => $node_count, "label" => $label, "type" => $cur_o_type);
			$node_count++;
		}
		
		$target_id = $nodes[$target]["id"];
		
		// Edge
		// Add edge
		array_push ($edges, array("source" => $source_id, "target" => $target_id, "label" => $edge_label));
		
		
	
		$result.="\n";
	  }

		// Construct graph	  
	  
			$dot .= "digraph G {\n";
			$dot .= "rankdir=LR;\n";
			
			foreach ($nodes as $node)
			{
				$dot .= "node" . $node["id"] . " [label=\"" . $node["label"] .  "\"";
				
				if ($node["type"] == "literal")
				{
					$dot .= ", shape=box";
				}
				if ($node["type"] == "bnode")
				{
					$dot .= ", shape=circle";
				}
				
				$dot .= "];\n";
			}
			
			foreach ($edges as $edge)
			{
				$dot .= "node" . $edge["source"] . " -> " . "node" . $edge["target"];
				
				// decoration
				
				$dot .= " [label=\"" . $edge["label"] . "\"];\n";
					}
			$dot .= "}\n\n";
			
	
	}
	else{
	  $dot = "couldn't parse ".$file_name.": ".$triples;
	}
return $dot;

}

?>

